package com.isoftstone.disk.obs.service.impl;

import com.isoftstone.disk.mybatis.entity.PtFileEntity;
import com.isoftstone.disk.mybatis.flexigrid.PadingRstType;
import com.isoftstone.disk.mybatis.flexigrid.PagingBean;
import com.isoftstone.disk.mybatis.ztree.ZtreeEntity;
import com.isoftstone.disk.obs.entity.SearchObsEntity;
import com.isoftstone.disk.obs.repository.ObsDao;
import com.isoftstone.disk.obs.service.ObsService;
import com.isoftstone.disk.spring.util.DataUtil;
import com.obs.services.ObsClient;
import com.obs.services.model.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

@Service
public class ObsServiceImpl implements ObsService {
    private Logger logger = LogManager.getLogger(this.getClass().getName());
    private static ObsClient obsClient = null;
    private static final String PARENT_ID = "-1";

    private static final int FILE_TYPE_FILE = 0;
    private static final int FILE_TYPE_DIR = 1;
    @Resource
    private ObsDao obsDao;
    @Value("${obs.end.point}")
    private String endpoint;
    @Value("${obs.ak}")
    private String ak;
    @Value("${obs.sk}")
    private String sk;
    @Value("${obs.bucket.name}")
    private String bucketName;
    private  synchronized ObsClient getObsIntanse(){
        if(obsClient == null){
            obsClient = new ObsClient(ak,sk,endpoint);
        }
        return obsClient;
    }

    @Override
    public void refreshObsFile() {
        ObsClient obsClient = getObsIntanse();
        ObjectListing list = obsClient.listObjects(bucketName);
        List<ObsObject> listObjects = list.getObjects();
        PtFileEntity ptFileEntity = null;
        Long length;
        obsDao.deleteFile();
        for(ObsObject obsObject:listObjects){
            ptFileEntity = new PtFileEntity();
            ptFileEntity.setFileUuid(DataUtil.getUUID());
            ptFileEntity.setParentUuid(PARENT_ID);
            ptFileEntity.setFileType(FILE_TYPE_FILE);
            length = obsObject.getMetadata().getContentLength();
            //文件大小为0，为文件夹
            if(length == 0l){
                ptFileEntity.setFileType(FILE_TYPE_DIR);
            }
            ptFileEntity.setFileName(obsObject.getObjectKey());
            ptFileEntity.setFilePath(obsObject.getObjectKey());
            obsDao.insertFile(ptFileEntity);
        }

    }

    @Override
    public int updatefile(String fileUUId) {
        return obsDao.updatefile(fileUUId);
    }

    @Override
    public int del(String fileUUId) {
        return obsDao.delFile(fileUUId);
    }

    @Override
    public PadingRstType<PtFileEntity> getFileList(SearchObsEntity entity, PagingBean paging) {
        paging.dealSortName(PtFileEntity.class);
        PadingRstType<PtFileEntity> padingRstType =  new PadingRstType<>();
        padingRstType.setPage(paging.getPage());
        List<PtFileEntity> list = obsDao.queryFile(entity,paging);
//        List<PtFileEntity> list2 = new ArrayList<>();
//        for (PtFileEntity ptFileEntity : list) {
//            Integer flag = ptFileEntity.getDelFlag();
//            if (flag==1){
//                list2.add(ptFileEntity);
//            }
//        }
        padingRstType.setRawRecords(list);
//        padingRstType.setRawRecords(list);
        Integer total =  obsDao.queryFileTotal(entity);
        padingRstType.setTotal(total);
        padingRstType.putItems();
        return padingRstType;
    }


    @Override
    public PadingRstType<PtFileEntity> getFileListByPage(SearchObsEntity entity, PagingBean paging) {
        paging.dealSortName(PtFileEntity.class);
        PadingRstType<PtFileEntity> padingRstType =  new PadingRstType<>();
        padingRstType.setPage(paging.getPage());
        List<PtFileEntity> list = obsDao.queryFileListByPage(entity,paging);
        padingRstType.setRawRecords(list);

        Integer total =  obsDao.queryFileTotal(entity);
        padingRstType.setTotal(total);
        padingRstType.putItems();
        return padingRstType;
    }

    @Override
    public void uploadFile(String fileName, InputStream inputStream) {
        ObsClient obsClient = getObsIntanse();
        obsClient.putObject(bucketName,fileName,inputStream);
        refreshObsFile();
    }

    @Override
    public ResponseEntity<byte[]> download(String fileUUId) {
        PtFileEntity ptFileEntity= obsDao.queryFileInfoById(fileUUId);
        ObsClient obsClient = getObsIntanse();
        ObsObject obsObject = obsClient.getObject(bucketName, ptFileEntity.getFilePath());
        InputStream is = obsObject.getObjectContent();

        byte[] contents = null;
        //缓存
        byte[] block = new byte[512];
        //每次读取的长度
        int length = 0;
        //自动关闭try(）
        try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){
            while ((length = is.read(block)) > 0 ){
                outputStream.write(block,0,length);
                outputStream.flush();
            }
            contents = outputStream.toByteArray();
        }catch (IOException e1) {
            e1.printStackTrace();
        }

        HttpHeaders headers =
                new HttpHeaders();
        headers.setContentDispositionFormData("attachment",
                ptFileEntity.getFileName());//告知浏览器以下载方式打开
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//设置MIME类型


        return new ResponseEntity<byte[]>(
                contents,
                headers,
                HttpStatus.CREATED);

    }

    @Override
    public void moveFile(String fileUUId,String dirUuid) {
        PtFileEntity fileFileEntity= obsDao.queryFileInfoById(fileUUId);
        PtFileEntity dirFileEntity= obsDao.queryFileInfoById(dirUuid);
        String newFileName = dirFileEntity.getFilePath()+fileFileEntity.getFilePath();

        // 修改数据库
        ObsClient obsClient = getObsIntanse();
        //ObsBucket newBucket = obsClient.createBucket(bucketName, fileName.substring(0, fileName.lastIndexOf("/")));
        obsClient.copyObject(bucketName, fileFileEntity.getFilePath(), bucketName,  newFileName);
        obsClient.deleteObject(bucketName, fileFileEntity.getFilePath());
        //        ptFileEntity.setFilePath(fileName.substring(0, fileName.lastIndexOf("/")) + File.pathSeparator + ptFileEntity.getFileName());
//        obsDao.moveFile(ptFileEntity);
        refreshObsFile();

    }

    @Override
    public void renameFile(String fileUUId,String fileName) {
        PtFileEntity ptFileEntity= obsDao.queryFileInfoById(fileUUId);
        ObsClient obsClient = getObsIntanse();
        ObsObject obsObject = obsClient.getObject(bucketName, ptFileEntity.getFilePath());
        InputStream is = obsObject.getObjectContent();
        obsClient.putObject(bucketName,fileName,is);
        obsClient.deleteObject(bucketName, ptFileEntity.getFilePath());
        refreshObsFile();
    }


    @Override
    public List<ZtreeEntity> queryDirZtreeListByFileId() {
        return obsDao.queryDirZtreeListByFileId();

    }
    @Override
    public String getFileUUid(String fileUUid) {
        ObsClient obsClient = getObsIntanse();
        PtFileEntity ptFileEntity= obsDao.queryFileInfoById(fileUUid);
        TemporarySignatureRequest request = new TemporarySignatureRequest();
        request.setBucketName(bucketName);
        request.setObjectKey(ptFileEntity.getFilePath());
        request.setRequestDate(new Date());
        request.setExpires(60*60);
        TemporarySignatureResponse signature = obsClient.createTemporarySignature(request);
        String url = signature.getSignedUrl();
        return url;
    }
}
